#!/usr/bin/env python
PACKAGE = "caros_camera"

from dynamic_reconfigure.parameter_generator_catkin import *

gen = ParameterGenerator()

## Capture parameters
capture = gen.add_group('Capture')
capture.add('AutoBlackLevel',   bool_t,   level=0, default=False,
            description="When set to true the image sensor black level will be adjusted automatically")
capture.add('AutoExposure',     bool_t,   level=0, default=False,
            description="When set to true the Exposure will be adjusted after each Capture command involving this camera.")
capture.add('AutoGain',         bool_t,   level=0, default=True,
            description="When set to true the Gain will be adjusted after each Capture command involving this camera.")
capture.add('Binning',          int_t,    level=0, default=1,     min=1,    max=2,
            description="A positive integer specifying the binning factor.")
capture.add('BlackLevelOffset', double_t, level=0, default=1.0,   min=0.0,  max=1.0,
            description="A number between 0.0 and 1.0. Values closer to zero will yield darker images, values closer to one will increase the image brightness at the expense of noise in dark image regions.")
capture.add('DisparityMapAOI',  bool_t,   level=0, default=False,
            description="When set to true the camera's capture AOI will be reduced.")
capture.add('Exposure',         double_t, level=0, default=10.0,   min=0.01, max=20.0,
            description="Specifies the camera's exposure time in milliseconds.")
capture.add('FrontLight',       bool_t,   level=0, default=True,
            description="When set to true the camera's front LED will be switched on for the duration of the image exposure.")
capture.add('Gain',             double_t, level=0, default=1.27,    min=1,    max=4,
            description="A value in the range 1..MaxGain specifying the camera's analog gain factor")
capture.add('GainBoost',        bool_t,   level=0, default=False,
            description="When set to true an additional analog gain boost on the camera will be enabled.")
capture.add('HardwareGamma',    bool_t,   level=0, default=False,
            description="When set to true the cameras analog gamma correction will be enabled.")
capture.add('HDR',              bool_t,   level=0, default=False,
            description="When set to true the HDR function of the camera will be enabled.")
capture.add('PixelClock',       int_t,    level=0, default=24,    min=7,    max=43,
            description="An integer number specifying the cameras pixel clock in MHz. Range: [7-43]")
capture.add('Projector',        bool_t,   level=0, default=True,
            description="When set to true the camera's pattern projector will be switched on for the duration of the image exposure.")
capture.add('TargetBrightness', int_t,    level=0, default=80,    min=40,   max=210,
            description="Positive number from 40 to 210, specifying the desired average gray value of both images.")
# TriggerMode enumerator
mode_enum = gen.enum([gen.const('Software',    int_t, 0, "The camera starts the exposure by software trigger when the Capture command is issued."),
                      gen.const('FallingEdge', int_t, 1, "The Capture command waits for a high-to-low transition on the trigger input before starting the exposure."),
                      gen.const('RisingEdge',  int_t, 2, "The Capture command waits for a low-to-high transition on the trigger input before starting the exposure.")],
                     "Specifies how an image capture is initiated.")
capture.add('TriggerMode',      int_t,    level=0, default=0,     min=0,    max=2, edit_method=mode_enum,
            description="Specifies how an image capture is initiated.")

## Stereo parameters
stereo = gen.add_group('Stereo')
stereo.add('MinimumDisparity',     int_t,    level=0, default=-64,   min=-256, max=256,
           description="The minimum disparity in pixels where correspondences in the stereo image pair are being searched. The resolution reductions by Scaling and Binning are automatically accounted for. The actual value used in the matching process is output in ScaledMinimumDisparity.")
stereo.add('NumberOfDisparities',  int_t,    level=0, default=128,   min=32,   max=256,
           description="The number of disparities in pixels where correspondences in the stereo image pair are being searched, starting at MinDisparity. The resolution reductions by Scaling and Binning are automatically accounted for. The actual value used in the matching process is output in ScaledNumberOfDisparities.")
stereo.add('Scaling',               double_t, level=0, default=1.0,   min=0.25, max=1.0,
           description="Scaling allows to reduce the camera resolution by an arbitrary non-integer factor during rectification. The camera raw images stay at their original size, but the rectified images, DisparityMap and PointMap will be scaled by the specified factor to improve stereo matching runtime. This allows you to choose you own tradeoff between image resolution and performance.")
# OptimizationProfile enumerator
profile_enum = gen.enum([ gen.const('Aligned',  int_t, 0, "Propagate cost along 4 paths, corresonding to the pixel axes of the rectified images."),
                          gen.const('Diagonal', int_t, 1, "Propagate cost on the 4 paths, corresponding the all 45 degree pixel diagonals."),
                          gen.const('AlignedAndDiagonal',  int_t, 2, "Propagate along all 8 paths, aligned and diagonal. This setting yields the best matching results, but slowest performance.")],
                        "The type of Semi-Global-Matching optimization carried out on the cost function.")
stereo.add('OptimizationProfile',      int_t,    level=0, default=2,     min=0,    max=2, edit_method=profile_enum,
           description="The type of Semi-Global-Matching optimization carried out on the cost function.")

# Advanced Matching Parameters
stereo.add('DepthChangeCost', int_t, level=0, default=5, min=1,max=40,
           description="The penalty for changes of +/- 1 disparity along an optimization path. This value must be smaller than DepthStepCost. Setting a larger value for DepthChangeCost will result in smoother surfaces, but some details might get lost when setting this value too large.")
stereo.add('DepthStepCost', int_t, level=0, default=30, min=2,max=41,
           description="The penalty for steps (changes of more than one disparity) along an optimization path. This value must be larger than DepthChangeCost. Setting a larger value for DepthStepCost will yield better detection of planar surfaces in low contrast areas, but too large values will lead to a loss of geometry details and precise object boundaries.(strictly larger than DepthChangeCost)")
stereo.add('ShadowingThreshold', int_t, level=0, default=1, min=-1, max=2,
           description="The disparity map is checked for occluded pixels. This is usually called 'left-right consistency check'. A pixel is only accepted if it is a mutually best match with the assigned right image pixel. Due to subpixel interpolation and half-occluded pixels, it is reasonable to allow small deviations from 'exact mutual' matches. This threshold sets the allowed range of mismatch in pixels.An integer specifying the threshold in disparities by which a pixel might be occluded by another pixel to still be accepted as valid. Negative values disable the occlusion detection and will leave wrongly associated regions in occluded image areas.")

## Postproc parameters
postproc = gen.add_group('Postproc')
postproc.add('UniquenessRatio', int_t, level=0, default=0, min=0, max=99,
             description="Filters the pixels depending on the uniqueness of the found correspondence. The value indicates the percentage, by which the cost of the next best correspondence must be larger (compared to the best correspondence), such that the pixel is accepted. Input para is an integer specifying the uniqueness margin in percent. Setting this parameter to 0 disables the uniqueness filter.")
postproc.add('MedianFilterRadius', int_t, level=0, default=0, min=0, max=2 ,
             description="Specifies the size of the median filter as radius in pixels, excluding the center pixel.The filter is applied to the disparity map. Median filtering will reduce noise inside surfaces while maintaining sharp edges, but object corners will be rounded. Input para is an integer specifying half the median filter window size in pixels, excluding the center pixel. Setting the filter radius to 0 will disable median filtering.")
postproc.add('SpeckleComponentThreshold', int_t, level=0, default=1, min=1, max=16 ,
             description="Defines how the image is divided into regions for speckle filtering. Whenever two neighboring pixel disparities differ by more than ComponentThreshold disparities, the two pixels are considered as belonging to separate regions. Consequently, each resulting region will not have discontinuities larger or equal to ComponentThreshold in it's disparity map area. The smaller this threshold is set, the smaller the resulting disparity regions will be. Thus setting a smaller ComponentThreshold will result in more regions being filtered out, because some regions fall apart and their sizes drop below RegionSize.")
postproc.add('SpeckleRegionSize', int_t, level=0, default=0, min=0, max=1000 ,
             description="The size in pixels of a disparity map region below which the region will be removed from the disparity map. The computation of the regions is controlled by ComponentThreshold. Input para is an integer specifying the size in pixels below which a region will be removed from the disparity map. Setting this parameter to 0 disables the speckle filter.")
postproc.add('FillBorderSpread', int_t, level=0, default=1, min=1, max=16 ,
             description="Defines which missing regions will be filled by setting a threshold on the maximum spread of the disparities on the region boundary. Setting this value reasonably small will ensure that only missing patches inside planar faces will be filled whereas gaps at depth discontinuities are kept unfilled. Input para is an integer specifying the maximum spread of the disparities at the fill region border.")
postproc.add('FillRegionSize', int_t, level=0, default=0, min=0, max=300 ,
             description="Defines an upper limit on the region size in pixels, up to which a region is accepted for filling. The region must also satisfy the BorderSpread condition to be filled. Input para is an integer specifying region size in pixels, up to which a missing region is being filled. Setting this parameter to 0 disables the hole filling filter.")

## Streaming parameters
stream = gen.add_group('Stream')
stream.add('Cloud',   bool_t,   level=0, default=True,
           description="When set to true the camera streams the point cloud. The rate can be adjusted changing PixelClock")
stream.add('Images',  bool_t,   level=0, default=True,
           description="When set to true the camera streams the images. The rate can be adjusted changing PixelClock")

exit(gen.generate(PACKAGE, "caros_camera", "Ensenso"))
